/**
 * 模糊搜索工具函数
 */

/**
 * 计算两个字符串的相似度（Levenshtein距离的变种，值越小越相似）
 * @param {String} str1 - 第一个字符串
 * @param {String} str2 - 第二个字符串
 * @return {Number} 相似度分数（越低越相似）
 */
function levenshteinDistance(str1, str2) {
  const track = Array(str2.length + 1).fill(null).map(() => 
    Array(str1.length + 1).fill(null));
  
  for (let i = 0; i <= str1.length; i += 1) {
    track[0][i] = i;
  }
  
  for (let j = 0; j <= str2.length; j += 1) {
    track[j][0] = j;
  }
  
  for (let j = 1; j <= str2.length; j += 1) {
    for (let i = 1; i <= str1.length; i += 1) {
      const indicator = str1[i - 1] === str2[j - 1] ? 0 : 1;
      track[j][i] = Math.min(
        track[j][i - 1] + 1, // 删除
        track[j - 1][i] + 1, // 插入
        track[j - 1][i - 1] + indicator, // 替换
      );
    }
  }
  
  return track[str2.length][str1.length];
}

/**
 * 判断一个字符串是否能模糊匹配另一个字符串
 * @param {String} text - 要检查的文本
 * @param {String} query - 搜索关键词
 * @param {Number} threshold - 相似度阈值，默认为2（越小越严格）
 * @return {Boolean} 是否匹配
 */
function fuzzyMatch(text, query, threshold = 2) {
  if (!text || !query) return false;
  
  // 如果包含，直接返回true
  if (text.toLowerCase().includes(query.toLowerCase())) return true;
  
  // 如果查询长度为1-2个字符，使用更严格的匹配
  if (query.length <= 2) {
    return text.toLowerCase().includes(query.toLowerCase());
  }
  
  // 计算文本中所有可能的子串与查询的相似度
  let minDistance = Infinity;
  const queryLen = query.length;
  
  // 拆分为单词后检查
  const words = text.split(/\s+/);
  for (const word of words) {
    // 如果单词以查询开头，直接匹配
    if (word.toLowerCase().startsWith(query.toLowerCase())) return true;
    
    // 如果单词包含查询的开头字符，可能是近似匹配
    const distance = levenshteinDistance(
      word.toLowerCase(),
      query.toLowerCase()
    );
    minDistance = Math.min(minDistance, distance);
  }
  
  // 如果还是没有匹配，检查整个文本
  if (minDistance > threshold) {
    for (let i = 0; i <= text.length - queryLen; i++) {
      const substr = text.substring(i, i + queryLen);
      const distance = levenshteinDistance(
        substr.toLowerCase(),
        query.toLowerCase()
      );
      minDistance = Math.min(minDistance, distance);
    }
  }
  
  return minDistance <= threshold;
}

/**
 * 模糊搜索过滤数组
 * @param {Array} items - 要过滤的数组
 * @param {String} query - 搜索关键词
 * @param {Array} fields - 要搜索的字段
 * @return {Array} 过滤后的数组
 */
function fuzzySearch(items, query, fields) {
  if (!query || query.trim() === '') return items;
  
  const searchTerms = query.toLowerCase().split(/\s+/);
  
  return items.filter(item => {
    return searchTerms.every(term => {
      return fields.some(field => {
        // 处理嵌套字段，如"user.name"
        const fieldParts = field.split('.');
        let fieldValue = item;
        
        for (const part of fieldParts) {
          if (!fieldValue) return false;
          fieldValue = fieldValue[part];
        }
        
        // 处理数组字段，如tags
        if (Array.isArray(fieldValue)) {
          return fieldValue.some(value => 
            typeof value === 'string' && fuzzyMatch(value, term)
          );
        }
        
        return typeof fieldValue === 'string' && fuzzyMatch(fieldValue, term);
      });
    });
  });
}

export default {
  fuzzySearch,
  fuzzyMatch,
  levenshteinDistance
}; 